﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Glucometer.ModuleHandler
{
    public class SetupModuleHandler : GlucometerModuleHandler
    {
        private DeviceSettings _tempSettingForEditing;

        d_EmptyArgument delegateToAutoEndingHandler;
        d_EmptyArgument delegateToEndingHandler;

        public SetupModuleHandler(IHarware hardware, DeviceMemory memory, DeviceSettings setting, DeviceStatus status)
            : base(hardware, memory, setting, status)
        {
            _tempSettingForEditing = new DeviceSettings(2000);
            delegateToAutoEndingHandler = new d_EmptyArgument(this.SetupModuleHandler_DeviceAutoEnding);
            delegateToEndingHandler = new d_EmptyArgument(SetupModuleHandler_DeviceEnding);
        }

        //IN CASE OF AUTO ENDING TRY TO SAVE IF ITS VALID DATE TIME
        void SetupModuleHandler_DeviceAutoEnding()
        {
            if (_tempSettingForEditing.IsValidDateSet())
            {
                //SAVE THE SETTINGS
                _settings.setSetting(_tempSettingForEditing.TestUnit, _tempSettingForEditing.getDateTime());
            }
        }

        void SetupModuleHandler_DeviceEnding()
        {
            //DEREGISTER FOR THE AUTOENDING EVENT
            DeviceAutoEnding -= delegateToAutoEndingHandler;
            //DEREGISTER FOR THE ENDING EVENT
            DeviceAutoEnding -= delegateToEndingHandler;
        }

        public override bool handleEventInMode(SoftwareEventsType set)
        {
            if (set == SoftwareEventsType.DOUBLE_CLICK)
            {
                //TRY TO MOVE TO NEXT EDIT POSITION
                //IF IT CANNOT MOVE THEN THERE IS SOME ERROR
                if (!_tempSettingForEditing.MoveToNextPosition())
                {
                    //ERROR DATE TIME SET SO GIVE ERROR BEEP
                    playBeep(BeeperStyle.SHORT_LONG_BEEP);
                }
                //AT THE END OF THE SETUP, THE EDIT POSITION IS NONE
                //IF THE SETUP EDIT POSITION IS NONE THEN SAVE THE SETTINGS AND GO TO ENDING
                if (_tempSettingForEditing.SetupUnitPosition == SetupModePosition.NONE)
                {
                    //SAVE THE SETTINGS
                    _settings.setSetting(_tempSettingForEditing.TestUnit, _tempSettingForEditing.getDateTime());

                    //END VOLUNTARILY
                    endDevice(EndingType.VOLUNTARY, OperationMode.SETUP);

                    return true;
                }

                //BLINK THE CURRENT EDIT POSITION
                _hardware.BlinkSetupPosition(_tempSettingForEditing.SetupUnitPosition);
            }
            else if (set == SoftwareEventsType.SHORT_CLICK)
            {
                _tempSettingForEditing.IncrementCurrentPositionSettingValue();

                //DISPLAY THE UPDATE VALUE IN DISPLAY
                _hardware.UpdateSetupPositionValue(_tempSettingForEditing.SetupUnitPosition, _tempSettingForEditing.CurrentSetupPositionValue);
            }
            else
            {
                //THIS IS UNDEFINED INTERACTION IGNORE IT   
                //playBeep(BeeperStyle.DOUBLE_BEEP);
            }

            return true;
        }

        public override bool doStatusCheck(SoftwareEventsType set)
        {
            //CHECK IF THE USB IS STILL CONNECTED
            //if (_hardware.getStatus(HardwareStatus.USB_INSERTED))
            if(_deviceStatus.usbConnected)
            {
                setLastError(ErrorCode.METERSTATUSCHECK_ERROR, "USB still connected.");
                return false;
            }

            //CHECK IF THE TEST STRIP IS STILL INSERTED
            //if (_hardware.getStatus(HardwareStatus.TEST_STRIP_INSERTED))
            if(_deviceStatus.testStripInserted)
            {
                setLastError(ErrorCode.METERSTATUSCHECK_ERROR, "Test strip still inserted.");
                return false;
            }

            //STATUS CHECK COMPLETE AND PASS SO RETURN TRUE
            return true;
        }

        public override bool doModeValidation(SoftwareEventsType set)
        {
            //NO MODULE VALIDATION IN SETUP MODE
            return true;
        }

        public override void loadMode()
        {
            //FIRST CLONE THE SETTING FOR EDITING
            _tempSettingForEditing.setSetting(_settings.TestUnit, _settings.getDateTime());

            //BLINK THE TEST UNIT 
            _hardware.BlinkSetupPosition(SetupModePosition.TEST_UNIT);

            //SHOW THE CURRENT TEST UNIT
            _hardware.UpdateSetupPositionValue(_tempSettingForEditing.SetupUnitPosition, _tempSettingForEditing.CurrentSetupPositionValue);

            //REGISTER FOR THE AUTOENDING EVENT
            DeviceAutoEnding += delegateToAutoEndingHandler;
            //REGISTER FOR THE ENDING EVENT
            DeviceEnding += delegateToEndingHandler;
        }
    }
}